package com.hxl.tech.gateway.auth.controller;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.hxl.tech.gateway.auth.annotate.ApiPrivilege;
import com.hxl.tech.gateway.auth.dto.Response;
import com.hxl.tech.gateway.auth.dto.limitrule.*;
import com.hxl.tech.gateway.auth.exception.AuthException;
import com.hxl.tech.gateway.auth.model.LimitRule;
import com.hxl.tech.gateway.auth.model.Resource;
import com.hxl.tech.gateway.auth.service.LimitRuleService;
import com.hxl.tech.gateway.auth.service.ResourceService;
import com.hxl.tech.gateway.auth.util.CopyUtil;
import com.hxl.tech.gateway.common.constant.AppConstant;
import com.hxl.tech.gateway.common.util.RedisUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 限流配置 Controller
 * @author soliddq
 * @date 2023-10-16
 */
@Api(value = "限流管理", tags = "限流管理")
@RestController
@RequiredArgsConstructor
public class LimitRuleController {

    private final LimitRuleService limitRuleService;
    private final ResourceService resourceService;

    @ApiPrivilege(needRole = AppConstant.ROLE_ADMIN)
    @GetMapping("gateway.auth.limit.ip.read")
    @ApiOperation(value = "读取限制IP访问配置", response = LimitIpDTO.class)
    public Response readLimitIp() {

        Resource resource = resourceService.read(new Resource.Id(AppConstant.RESOURCE_MERCHANT_DEFAULT, AppConstant.RESOURCE_IP_LIMIT));
        resource = Objects.isNull(resource) ? new Resource() : resource;
        return Response.createSuccess(JSONObject.parseObject(resource.getResourceValue(), LimitIpDTO.class));
    }

    @ApiPrivilege(needRole = AppConstant.ROLE_ADMIN)
    @PostMapping("gateway.auth.limit.ip.save")
    @ApiOperation(value = "保存限制IP访问配置", response = LimitIpDTO.class)
    public Response saveLimitIp(@RequestBody @Validated LimitIpSaveDTO saveDTO) {

        if (saveDTO.getLimitType().equals(1) && CollUtil.isEmpty(saveDTO.getWhiteIps())) {
            throw new AuthException("开启ip白名单模式，白名单列表不能为空");
        }
        if (saveDTO.getLimitType().equals(1) && CollUtil.isEmpty(saveDTO.getWhiteIps())) {
            throw new AuthException("开启ip黑名单模式，黑名单列表不能为空");
        }

        Resource resource = new Resource();
        resource.setId(new Resource.Id(AppConstant.RESOURCE_MERCHANT_DEFAULT, AppConstant.RESOURCE_IP_LIMIT));
        resource.setResourceValue(JSONObject.toJSONString(saveDTO));
        resourceService.saveOrUpdate(resource);

        RedisUtil.set(AppConstant.REDIS_LIMIT_IP_RULE, resource.getResourceValue(), 0 , TimeUnit.DAYS);
        return Response.createSuccess(saveDTO);
    }

    @ApiPrivilege(needRole = AppConstant.ROLE_ADMIN)
    @PostMapping("gateway.auth.limit.rule.read")
    @ApiOperation(value = "读取限制Rate访问配置", response = LimitRuleDTO.class)
    public Response readLimitRate(@RequestBody @Validated LimitRuleIdDTO idDTO) {

        return Response.createSuccess(CopyUtil.to(limitRuleService.read(idDTO.getRuleId()), LimitRuleDTO.class));
    }

    @ApiPrivilege(needRole = AppConstant.ROLE_ADMIN)
    @PostMapping("gateway.auth.limit.rule.page")
    @ApiOperation(value = "分页查询限制Rate访问配置", response = LimitRuleDTO.class, responseContainer = "List")
    public Response pageLimitRate(@RequestBody @Validated LimitRuleFindDTO findDTO) {

        return Response.createSuccess(CopyUtil.toPage(limitRuleService.page(findDTO), LimitRuleDTO.class));
    }

    @ApiPrivilege(needRole = AppConstant.ROLE_ADMIN)
    @PostMapping("gateway.auth.limit.rule.save")
    @ApiOperation(value = "新增限制Rate访问配置", response = LimitRuleDTO.class)
    public Response saveLimitRate(@RequestBody @Validated LimitRuleSaveDTO saveDTO) {

        return Response.createSuccess(CopyUtil.to(limitRuleService.save(CopyUtil.to(saveDTO, LimitRule.class)), LimitRuleDTO.class));
    }

    @ApiPrivilege(needRole = AppConstant.ROLE_ADMIN)
    @PostMapping("gateway.auth.limit.rule.update")
    @ApiOperation(value = "更新限制Rate访问配置", response = LimitRuleDTO.class)
    public Response updateLimitRate(@RequestBody @Validated LimitRuleUpdateDTO updateDTO) {

        return Response.createSuccess(CopyUtil.to(limitRuleService.update(CopyUtil.to(updateDTO, LimitRule.class)), LimitRuleDTO.class));
    }

    @ApiPrivilege(needRole = AppConstant.ROLE_ADMIN)
    @PostMapping("gateway.auth.limit.rule.delete")
    @ApiOperation(value = "删除限制Rate访问配置", response = LimitRuleDTO.class)
    public Response deleteLimitRate(@RequestBody @Validated LimitRuleIdDTO idDTO) {

        limitRuleService.delete(idDTO.getRuleId());
        return Response.createSuccess();
    }

}
